package org.wujiangbo.interceptor;

import org.wujiangbo.annotation.CheckIdempotent;
import org.wujiangbo.service.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @desc 接口幂等性校验的拦截器
 * @author wujiangbo(weixin:wjb1134135987)
 */
@Component
public class CheckIdempotentInterceptor implements HandlerInterceptor{

    @Autowired
    private TokenService tokenService;

    /**
     * 前置处理
     * 该方法将在请求处理之前进行调用
     */
    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {
        //判断：如果拦截到的资源不是方法，那就直接返回true，不需要走后面的逻辑判断
        if (!(handler instanceof HandlerMethod)) {
            //放行
            return true;
        }
        //执行到这里，说明请求的是方法
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        //获取方法对象
        Method method = handlerMethod.getMethod();
        //获取方法上面的 CheckIdempotent 注解对象
        CheckIdempotent methodAnnotation = method.getAnnotation(CheckIdempotent.class);
        if (methodAnnotation != null) {
            //不为空，说明该方法打上了 CheckIdempotent 注解，那么就可以做一些逻辑校验或者判断了
            try {
                //被CheckIdempotent注解标记的类，都需要做token校验
                return tokenService.checkToken(request);
            }catch (Exception ex){
                writeReturnJson(response, ex.getMessage());
                return false;
            }
        }
        //必须返回true，否则会拦截掉所有请求，不会执行controller方法中的内容了
        return true;
    }

    //返回提示信息给前端
    private void writeReturnJson(HttpServletResponse response, String message){
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        response.setStatus(404);
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            outputStream.print(message);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}